﻿using General.Core.Config;
using General.Entities.Models;
using General.Entities.ViewData.Article;
using General.Mvc.Filters;
using General.Services.Article;
using General.Services.Template;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace General.Mvc.Controllers.Web
{
    [ServiceFilter(typeof(PageTemplateFilter))]
    public class ArticleController : Controller
    {
        private readonly ITemplateService templateService;
        private readonly IArticleService articleService;
        private readonly IArticleCateService articleCateService;
        private readonly IMemoryCache memoryCache;

        public ArticleController(ITemplateService templateService,
            IArticleService articleService,
            IArticleCateService articleCateService,
            IMemoryCache memoryCache)
        {
            this.templateService = templateService;
            this.articleService = articleService;
            this.articleCateService = articleCateService;
            this.memoryCache = memoryCache;
        }

        /// <summary>
        /// 文章列表页
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("/List/{id}.html")]
        [Route("/List/{id}/{page}.html")]
        //[Route("/List_{id}_{page}.html")]
        public async Task<IActionResult> GetArticleList(int id, int page = 1)
        {
            var indexHtml = await templateService.GetPageHtmlContent(WebSiteTemplateConfig.Site_Template_List_Info.name);
            var listHtml = WebSiteTemplateConfig.Site_Template_List_Info.htmlContent;
            var WebSite_UniqueIdentification = memoryCache.Get("WebSite_UniqueIdentification").ToString();
            tc_articlecate articleCateModel;
            if (WebSiteTemplateConfig.WebSite_OpenDataCache)
            {
                var result = await RedisHelper.GetAsync(WebSite_UniqueIdentification + WebSiteConfig.Redis_ArticleListInfo_Key + id.ToString());
                if (!string.IsNullOrEmpty(result))
                {
                    articleCateModel = JsonHelper.Deserialize<tc_articlecate>(result);
                    if (articleCateModel == null || articleCateModel.status != 1)
                    {
                        return new RedirectToActionResult("404", "Error", "");
                    }
                }
                else
                {
                    articleCateModel = await articleCateService.GetInfoById(id);
                    //写入缓存
                    RedisHelper.SetAsync(WebSite_UniqueIdentification + WebSiteConfig.Redis_ArticleListInfo_Key + id.ToString(), JsonHelper.Serialize(articleCateModel));
                }
            }
            else
            {
                articleCateModel = await articleCateService.GetInfoById(id);
            }
            if (articleCateModel == null || articleCateModel.status != 1)
            {
                return new RedirectToActionResult("404", "Error", "");
            }

            #region SEO
            var seoTitle = memoryCache.Get("SEO_List_Title").ToString();
            seoTitle = seoTitle.Replace("@Title", articleCateModel.name);
            indexHtml = indexHtml.Replace("@Title", seoTitle);
            if (string.IsNullOrWhiteSpace(articleCateModel.keywords))
            {
                var seoKeyWords = memoryCache.Get("SEO_List_KeyWords").ToString();
                seoKeyWords = seoKeyWords.Replace("@Title", articleCateModel.name);
                indexHtml = indexHtml.Replace("@KeyWords", seoKeyWords);
            }
            else
            {
                indexHtml = indexHtml.Replace("@KeyWords", articleCateModel.keywords);
            }

            if (string.IsNullOrWhiteSpace(articleCateModel.description))
            {
                var seoDescription = memoryCache.Get("SEO_List_Description").ToString();
                seoDescription = seoDescription.Replace("@Title", articleCateModel.name);
                indexHtml = indexHtml.Replace("@Description", seoDescription);
            }
            else
            {
                indexHtml = indexHtml.Replace("@Description", articleCateModel.description);
            }
            #endregion
            listHtml = await LoadCateArticleInfo(listHtml, id);

            listHtml = listHtml.Replace("@Id", articleCateModel.id.ToString()).Replace("@Name", articleCateModel.name).Replace("@Image", articleCateModel.image).Replace("@Count", articleCateModel.count.ToString());

            listHtml = await LoadCateInfo(listHtml);


            indexHtml = indexHtml.Replace("@Section_Main", listHtml);

            HttpContext.Response.ContentType = "text/html";
            return Content(indexHtml);
        }


        /// <summary>
        /// 获取文章列表接口
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("List/GetArticleInfo")]
        public async Task<IActionResult> GetArticleInfo(int? cateid, int page = 1, int limit = 10)
        {
            var data = JsonHelper.Serialize(await articleService.GetNewList(limit, page, cateid));
            return Content(data);
        }




        /// <summary>
        /// 加载文章页 文章信息
        /// </summary>
        /// <param name="html"></param>
        /// <returns></returns>
        public async Task<string> LoadCateArticleInfo(string html, int cateid)
        {
            var WebSite_UniqueIdentification = memoryCache.Get("WebSite_UniqueIdentification").ToString();
            if (WebSiteTemplateConfig.WebSite_OpenDataCache)
            {
                var memoryDataInfo = await RedisHelper.GetAsync(WebSite_UniqueIdentification + WebSiteConfig.Redis_List_Article_Key + cateid.ToString());
                if (memoryDataInfo != null)
                {
                    return Regex.Replace(html, "@Article_Start[.\\s\\S]*@Article_End", memoryDataInfo.ToString(), RegexOptions.IgnoreCase);
                }
            }

            StringBuilder OutHtml = new StringBuilder();
            MatchCollection mc = Regex.Matches(html, "(?<=(@Article_Start))[.\\s\\S]*?(?=(@Article_End))");
            foreach (Match m in mc)
            {
                var arr = m.Value.Split(",", StringSplitOptions.RemoveEmptyEntries);
                var parmList = new List<string>() { "", "" };
                for (int i = 0; i < arr.Length; i++)
                {
                    parmList[i] = arr[i];
                }
                List<SimpleArticleInfo> articleInfo = await articleService.GetNewList(Convert.ToInt32(parmList[1].Trim()), 1, cateid);

                foreach (var item in articleInfo)
                {
                    var temp = parmList[0].Replace("@Title", item.title).Replace("@Id", item.id.ToString()).Replace("@Thumb", item.thumb).Replace("@AuthorName", item.username).Replace("@AuthorImage", item.userImage).Replace("@CateName", item.cateName).Replace("@CateId", item.cateId.ToString()).Replace("@Time", item.creatTime).Replace("@Hits", item.hits.ToString());
                    OutHtml.Append(temp);
                }



                if (WebSiteTemplateConfig.WebSite_OpenDataCache)
                    RedisHelper.SetAsync(WebSite_UniqueIdentification + WebSiteConfig.Redis_List_Article_Key + cateid.ToString(), OutHtml.ToString());
                break;
            }
            if (mc.Count == 0)
            {
                return html;
            }
            return Regex.Replace(html, "@Article_Start[.\\s\\S]*@Article_End", OutHtml.ToString(), RegexOptions.IgnoreCase);

        }




        /// <summary>
        /// 加载列表页类别信息
        /// </summary>
        /// <param name="html"></param>
        /// <returns></returns>
        public async Task<string> LoadCateInfo(string html)
        {
            if (WebSiteTemplateConfig.WebSite_OpenDataCache)
            {
                var memoryDataInfo = memoryCache.Get(WebSiteConfig.WebSite_List_AllCate_Key);
                if (memoryDataInfo != null)
                {
                    return Regex.Replace(html, "@CateList_Start[.\\s\\S]*@CateList_End", memoryDataInfo.ToString(), RegexOptions.IgnoreCase);
                }
            }
            var cateListInfo = await articleCateService.GetListBySort();
            StringBuilder OutHtml = new StringBuilder();
            MatchCollection mc = Regex.Matches(html, "(?<=(@CateList_Start))[.\\s\\S]*?(?=(@CateList_End))");
            foreach (Match m in mc)
            {
                foreach (var item in cateListInfo)
                {
                    var temp = m.Value.Replace("@List_Count", item.count.ToString()).Replace("@List_Id", item.id.ToString()).Replace("@List_Image", item.image).Replace("@List_Name", item.name);
                    OutHtml.Append(temp);
                }



                if (WebSiteTemplateConfig.WebSite_OpenDataCache)
                    memoryCache.Set(WebSiteConfig.WebSite_List_AllCate_Key, OutHtml);
                break;
            }
            if (mc.Count == 0)
            {
                return html;
            }
            return Regex.Replace(html, "@CateList_Start[.\\s\\S]*@CateList_End", OutHtml.ToString(), RegexOptions.IgnoreCase);
        }


        /// <summary>
        /// 文章详细信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        [Route("/Detail/{id}.html")]
        [Route("/Detail/{id}")]
        [Route("/Article/{id}.html")]
        [Route("/Article/{id}")]
        [Route("/{id}.html")]
        public async Task<IActionResult> Detail(int id)
        {
            var indexHtml = await templateService.GetPageHtmlContent(WebSiteTemplateConfig.Site_Template_Detail_Info.name);
            var detailHtml = WebSiteTemplateConfig.Site_Template_Detail_Info.htmlContent;
            ArticleInfo articleModel;
            var WebSite_UniqueIdentification = memoryCache.Get("WebSite_UniqueIdentification").ToString();
            if (WebSiteTemplateConfig.WebSite_OpenDataCache)
            {
                var hData = await RedisHelper.HGetAllAsync(WebSite_UniqueIdentification + WebSiteConfig.Redis_Article_Key + id.ToString());
                if (hData.Count == 2)
                {
                    articleModel = JsonHelper.Deserialize<ArticleInfo>(hData["ArticleInfo"]);
                    articleModel.hits = Convert.ToInt32(hData["Hits"]);
                }
                else
                {
                    articleModel = await articleService.GetArticleInfoById(id);
                    if (articleModel == null || articleModel.status != 1)
                    {
                        return new RedirectToActionResult("404", "Error", "");
                    }
                    //写入缓存
                    RedisHelper.HMSetAsync(WebSite_UniqueIdentification + WebSiteConfig.Redis_Article_Key + id.ToString(), new string[] { "ArticleInfo", JsonHelper.Serialize(articleModel), "Hits", articleModel.hits.ToString() });
                }
            }
            else
            {
                articleModel = await articleService.GetArticleInfoById(id);
            }



            if (articleModel == null || articleModel.status != 1)
            {
                return new RedirectToActionResult("404", "Error", "");
            }
            #region SEO
            var seoTitle = memoryCache.Get("SEO_Detail_Title").ToString();
            seoTitle = seoTitle.Replace("@Title", articleModel.title);
            indexHtml = indexHtml.Replace("@Title", seoTitle);
            if (string.IsNullOrWhiteSpace(articleModel.keyWords))
            {
                var seoKeyWords = memoryCache.Get("SEO_Detail_KeyWords").ToString();
                seoKeyWords = seoKeyWords.Replace("@Title", articleModel.title);
                indexHtml = indexHtml.Replace("@KeyWords", seoKeyWords);
            }
            else
            {
                indexHtml = indexHtml.Replace("@KeyWords", articleModel.keyWords);
            }

            if (string.IsNullOrWhiteSpace(articleModel.description))
            {
                var seoDescription = memoryCache.Get("SEO_Detail_Description").ToString();
                seoDescription = seoDescription.Replace("@Title", articleModel.title);
                indexHtml = indexHtml.Replace("@Description", seoDescription);
            }
            else
            {
                indexHtml = indexHtml.Replace("@Description", articleModel.description);
            }
            #endregion

            detailHtml = detailHtml.Replace("@CateName", articleModel.cateName).Replace("@AuthorId", articleModel.author.ToString()).Replace("@CateId", articleModel.cateId.ToString()).Replace("@CateName", articleModel.cateName).Replace("@CopyFrom", articleModel.copyfrom).Replace("@Time", articleModel.createTime.ToString("yyyy-MM-dd HH:mm:ss")).Replace("@Hits", articleModel.hits.ToString()).Replace("@Id", articleModel.id.ToString()).Replace("@Intro", articleModel.intro).Replace("@AuthorName", articleModel.nickname).Replace("@SubHead", articleModel.subhead).Replace("@Thumb", articleModel.thumb).Replace("@Title", articleModel.title).Replace("@AuthorImage", articleModel.userImage).Replace("@Content", articleModel.content);

            #region 文章上/下一篇
            if (articleModel.lastModel == null)
            {
                detailHtml = detailHtml.Replace("@LastArticle_Id", "0").Replace("@LastArticle_Title", "无").Replace("@LastArticle_Thumb", "").Replace("@LastArticle_AuthorName", "无").Replace("@LastArticle_AuthorImage", "/images/user.png");
            }
            else
            {
                detailHtml = detailHtml.Replace("@LastArticle_Id", articleModel.lastModel.id.ToString()).Replace("@LastArticle_Title", articleModel.lastModel.title).Replace("@LastArticle_Thumb", articleModel.lastModel.thumb).Replace("@LastArticle_AuthorName", articleModel.lastModel.username).Replace("@LastArticle_AuthorImage", articleModel.lastModel.userImage);
            }

            if (articleModel.nextModel == null)
            {
                detailHtml = detailHtml.Replace("@NextArticle_Id", "0").Replace("@NextArticle_Title", "无").Replace("@NextArticle_Thumb", "").Replace("@NextArticle_AuthorName", "无").Replace("@NextArticle_AuthorImage", "/images/user.png");
            }
            else
            {
                detailHtml = detailHtml.Replace("@NextArticle_Id", articleModel.nextModel.id.ToString()).Replace("@NextArticle_Title", articleModel.nextModel.title).Replace("@NextArticle_Thumb", articleModel.nextModel.thumb).Replace("@NextArticle_AuthorName", articleModel.nextModel.username).Replace("@NextArticle_AuthorImage", articleModel.nextModel.userImage);
            }
            #endregion


            #region 最新文章
            detailHtml = await LoadNewDetailInfo(detailHtml);
            #endregion




            indexHtml = indexHtml.Replace("@Section_Main", detailHtml);

            //增加点击量
            await articleService.AddClickCount(articleModel.id, articleModel.hits);

            HttpContext.Response.ContentType = "text/html";
            return Content(indexHtml);
        }


        /// <summary>
        /// 加载最新文章信息
        /// </summary>
        /// <param name="html"></param>
        /// <returns></returns>
        public async Task<string> LoadNewDetailInfo(string html)
        {
            if (WebSiteTemplateConfig.WebSite_OpenDataCache)
            {
                var memoryDataInfo = memoryCache.Get(WebSiteConfig.WebSite_Detail_NewArticle_Key);
                if (memoryDataInfo != null)
                {
                    return Regex.Replace(html, "@Article_New_Start[.\\s\\S]*@Article_New_End", memoryDataInfo.ToString(), RegexOptions.IgnoreCase);
                }
            }
            List<SimpleArticleInfo> articleInfo = await articleService.GetNewList();
            StringBuilder OutHtml = new StringBuilder();
            MatchCollection mc = Regex.Matches(html, "(?<=(@Article_New_Start))[.\\s\\S]*?(?=(@Article_New_End))");
            foreach (Match m in mc)
            {
                var arr = m.Value.Split(",", StringSplitOptions.RemoveEmptyEntries);
                var parmList = new List<string>() { "", "" };
                for (int i = 0; i < arr.Length; i++)
                {
                    parmList[i] = arr[i];
                }

                foreach (var item in articleInfo.Take(Convert.ToInt32(parmList[1].Trim())))
                {
                    var temp = parmList[0].Replace("@New_Title", item.title).Replace("@New_Id", item.id.ToString()).Replace("@New_Thumb", item.thumb).Replace("@New_AuthorName", item.username).Replace("@New_AuthorImage", item.userImage).Replace("@New_CateName", item.cateName).Replace("@New_CateId", item.cateId.ToString()).Replace("@New_Time", item.creatTime).Replace("@New_Hits", item.hits.ToString());
                    OutHtml.Append(temp);
                }



                if (WebSiteTemplateConfig.WebSite_OpenDataCache)
                    memoryCache.Set(WebSiteConfig.WebSite_Detail_NewArticle_Key, OutHtml);
                break;
            }
            if (mc.Count == 0)
            {
                return html;
            }
            return Regex.Replace(html, "@Article_New_Start[.\\s\\S]*@Article_New_End", OutHtml.ToString(), RegexOptions.IgnoreCase);
        }


    }
}
